Добавить шаблон в n-ю строку, если в файле (n-x) строк [RHEL6]

Вы очень близко. Вы можете делать что хотите с помощью

while read line; do pushd "$line"; done < <(find "$(pwd)" -type d)

Проблема с вашей командой в том, что pushd, как и cd, должно быть выполнено в основном (родительском )процессе, чтобы быть полезным, и (с некоторыми вариациями в зависимости от того, как настроена ваша система ), команды в конвейере выполняются в подпроцессах (дочерних процессах ). < <(cmd)волшебным образом дает вам трубку без предоставления вам трубопровода.

Для этого требуется, чтобы вы использовали bash (или, может быть, один из других продвинутых снарядов? ), поскольку POSIX не поддерживает <(cmd).

Подход xargs, к сожалению, был обречен на провал, потому что pushd(, как и cd), является встроенной командой оболочки (т. е. не существует программы с именем pushd), и xargsтребует внешней исполняемой программы. Вы можете получить вывод, что (почти )выглядит правильно с помощью этой команды:

$ find "$(pwd)" -type d | xargs -i sh -c 'pushd "$1"' sh
~/foo ~/foo
~/foo/bar1 ~/foo
~/foo/bar2 ~/foo
~/foo/bar3 ~/foo

но это выполняет оболочку как внешнюю программу, и делать это (независимо )для каждого каталога. Это немного ближе:

$ find "$(pwd)" -type d | xargs sh -c 'for line do pushd "$line"; done' sh
~/foo ~/foo
~/foo/bar1 ~/foo ~/foo
~/foo/bar2 ~/foo/bar1 ~/foo ~/foo
~/foo/bar3 ~/foo/bar2 ~/foo/bar1 ~/foo ~/foo

выполнение одного процесса оболочки, и сказать ему перебрать все каталоги. Как вы видете, эта техника аналогична вашей второй попытке (и моему ответу ), и результат такой же, как и во второй попытке — вы получаете новый процесс оболочки, который вызывает pushdчетыре раза, и заканчивается стеком каталогов, который имеет пять уровней глубины (двойной подсчет начального каталога )— но этот новый процесс оболочки находится в подпроцессе, и к тому времени, когда вы увидите следующее приглашение оболочки, этот процесс оболочки уже завершен.

Для справки: эта команда чем-то похожа на ответ, который я дал пару лет назад . Стефан Шазела обсуждает конструкция команды sh -c long_complex_shell_command shздесь и здесь .

0
07.09.2018, 16:39
3 ответа

Вы можете дополнить файл несколькими пустыми строками, чтобы в нем было как минимум 4 строки:

{ cat file; echo; echo; echo; } | sed -e '4i pattern' 

Если вы хотите впоследствии обрезать завершающие пустые строки, вы можете передать это в:

| sed -n 'H; ${g; s/^\n//; s/\n\+$//; p}' 

или

| tac | awk '/./{p=1}p' | tac 

Или добавить только минимальное количество пустых строк:

{ cat file; for ((i=$(wc -l <file); i<3; i++)); do echo; done; } | sed '3a pattern'

Обратите внимание, что программа sed была изменена на добавление после строки 3 вместо вставки перед строкой 4.

1
28.01.2020, 02:31

Проверьте, достаточно ли строк fileс помощьюwc -l(подсчета строк ).

Отображать предупреждение, если в файле недостаточно строк.

[ $(cat file | wc -l) -ge 4 ] && sed -i '4s pattern' file || echo "not enough lines"
0
28.01.2020, 02:31
while [ $(wc -l <file) -lt 4 ] ; do
    echo >> file
done
sed -i '4i pattern' file
1
28.01.2020, 02:31

Теги

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