перенаправление вывода при циклическом просмотре файла для запуска команды для каждой строки

Просто, хотя и не важно, будет ли он читать файл много раз:

sed 's/ /\n/g' file.txt | sort | uniq | while read -r word; do
  printf "%s:%d\n" "$word" "$(grep -Fw "$word" file.txt | wc -l)"
done

РЕДАКТИРОВАТЬ :Несмотря на преобразование пробелов в символы новой строки, при этом учитываются строки, в которых встречается каждое слово, а не сами слова. Это дает результат:

0:1
1:1
2:1
a:1
different:1
hello:1
is:3
man:2
one:1
possible:1
the:3
this:1
world:2

, который представляет собой символ -на символ -, идентичный результату примера OP.

1
04.03.2021, 13:04
3 ответа

i googled a bit and found this find mydir -name.git -type d

Вы могли бы сделать что-то подобное, может быть:

find. -name '.git' -type d -print -execdir git status \;

Это будет искать каталоги с именем .git, затем для каждого напечатать путь к нему, перейти в содержащий каталог и запустить там git status.(find -execзапустит команду в исходном каталоге, -execdirперейдет туда, где был соответствующий файл/каталог.)

Вы получите результат вида

./this-stuff/.git
On branch master
Your branch is up to date with 'origin/master'.

, и потребуются дополнительные хитрости, чтобы -обработать из него .git. (. -exec sh -c 'echo "${1%.git}"' sh {} \;вместо -print.)

В общем, findможет работать, если вы хотите что-то сделать со всеми файлами/каталогами в некотором поддереве, соблюдая какое-то условие, очевидное из метаданных файлов. Но если у вас есть существующий список, цикл оболочки — лучший способ его обработки.

3
18.03.2021, 22:27

При перенаправлении на новую строку применяется к пустой команде; чтобы исправить это, поместите его на строку done:

while IFS= read -r line; 
    do  echo "$line"
        (cd "$line"; git status)
done < repo.list > status.txt

См. также Понимание IFS и Понимание "IFS= read -r line" и связанные вопросы для получения информации о тонкостях, затрагивающих read.

Использование подоболочки для cdи git statusвместе означает, что смена каталогов не повлияет на последующие итерации цикла или даже на оболочку, выполняющую while.

4
18.03.2021, 22:27

Ваша проблема представляет собой простую опечатку, как уже объяснил Стивен .

Задача запуска git statusв каждом каталоге, заданном строкой в ​​файле, может быть выполнена с использованием xargsи:

xargs -I {} git -C {} status <repo.list >status.txt

Это вызывает git -C {} statusдля каждой строки в файле repo.list. {}будет заменено строкой, прочитанной из файла, а опция -Cдля gitзаставит утилиту использовать альтернативный каталог для команды statussub -вместо текущего.

Чтобы путь к репозиторию выводился перед каждым вызовом git status, вызовите скрипт sh -c:

xargs -I {} sh -c 'printf "REPOSITORY: %s\n" "$1"; git -C "$1" status' sh {} <repo.list >status.txt

Внутри скрипта sh -cпуть к репозиторию задается как "$1".

1
18.03.2021, 22:27

Теги

Похожие вопросы