Форматирование вывода с использованием printf с помощью xargs

0

Я хочу найти в моей кодовой базе вхождение строки, а затем получить отформатированный вывод в виде имени файла, номера строки и области кода. Я получил это, как я хотел в первой строке вывода, но следующие строки теряют желаемое форматирование.

$ find src/ -name "*.js" | xargs grep --null -E -n 'filter\(|map\(' | xargs -0 printf "%-100s%-5s%-100s" > test.txt

Вывод следующий: (прокрутите вправо, чтобы увидеть полную строку)

src/components/AppRouterSwitch.js                                                                   15:    return _Routes.map((route, index) => {
src/components/forms/UserEditForm/UserEditForm.js36:    const options = UserTypes.map((type, index) => <option key={index} value={type.type}>{type.name}</option>);
src/components/pages/AdminPage/SolutionManagementEditPage/SolutionManagementEditPage.js119:        templates:state.templates.filter(item=>item.SOLUTIONID ==id)
src/components/pages/AdminPage/SolutionManagementEditPage/SolutionManagementEditPage.js120:            .map(item=>{return{

Первый ряд выглядит так, как я хочу. Следующее теряет желаемое форматирование. Завершение строки формата printf с помощью /nне добивается цели.

Максимум
источник
1
Попробуйте использовать стандартную опцию grep -l(строчная L)
малый
1
@malyy Я пробовал это с некоторыми изменениями, но безуспешно. Я не понимаю, как опция -l поможет мне. -l, --files-with-match Подавить нормальный вывод; вместо этого напечатайте имя каждого входного файла, из которого обычно выводился бы вывод. Сканирование остановится при первом совпадении.
Макс
пожалуйста, проверьте мой ответ и уточните, действительно ли вам нужно двоеточие (:) после номера строки
qubert

Ответы:

2
find src/ -type f -name '*.js' -exec grep -Hn -E -- 'filter\(|map\(' {} + |
    awk -F: '{printf "%-100s%-5s%-100s\n", $1, $2, substr($0, length($1) + length($2) + 3)}'

-HВариант grepзаставит его напечатать имя файла , даже при вызове с одним файлом в качестве аргумента. Параметр -type fпоиска необходим для того, чтобы пропустить неработающие ссылки и каталоги, которые случайно названы *.js.

Или даже проще, избавиться от grep полностью (спасибо @don_crissti за предложение):

find src/ -type f -name '*.js' -exec awk '/filter\(|map\(/{printf "%-100s%-5s%-100s\n", FILENAME, FNR, $0}' {} +
qubert
источник
Элегантное решение, как раз то, что мне нужно. Толстая кишка не нужна.
Макс
0

manделает это немного неясным. «Сканирование остановится при первом совпадении» - означает, что будут напечатаны все имена файлов, но сканирование по совпадающему слову будет остановлено при первом совпадении. Страница руководства GNU grep разъясняет это:

-l
--files-with-matches
Suppress normal output; instead print the name of each input file from which output would normally have been printed. The scanning of each file stops on the first match. (-l is specified by POSIX.)

Вот пример:

$grep -iR Intel * 
2018/jan/cpu.txt:Intel i9 
2018/motherboard.txt:Intel Motherboard 
hardware.txt:Intel Corei7
#the same result as you provided;

$grep -iRl Intel * 
2018/jan/cpu.txt
2018/motherboard.txt
hardware.txt
#the desired result
Malyy
источник
Не совсем то, что я хотел. Пожалуйста, прокрутите вывод вправо, и вы увидите, что я также хочу номер строки и строку кода, но отформатирован как в первой строке.
Макс