bash -c -O extglob 'stat /path/todir/!(.|..)'
-O extglob
включает дополнительные операторы сопоставления с образцом, в том числе !(pattern-list)
для отрицания.
[-+]O [shopt_option]
shopt_option is one of the shell options accepted by the shopt builtin (see
SHELL BUILTIN COMMANDS below). If shopt_option is present, -O sets the
value of that option; +O unsets it.
If the extglob shell option is enabled using the shopt builtin, several extended pattern matching
operators are recognized. In the following description, a pattern-list is a list of one or more
patterns separated by a |. Composite patterns may be formed using one or more of the following
sub-patterns:
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
@(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
Цитата '
делает так, что переменная интерпретируется буквально как $i
вместо 30, 31, 32 и т. д.
Я сделал изменение ниже, заключив все выражение sed в кавычки "
:
for (( i=30; i<=44; i++))
do
sed "s/0.340d0/0.${i}0d0/g" 1.txt > temp.txt
cp temp.txt "$i".txt
done
В вашем коде есть три проблемы:
Вы используете строку в одинарных кавычках в качестве выражения sed
, не позволяя оболочке расширять переменную в замещающей части команды s///
.
Вы меняете исходный 1.txt
файл на месте, так что даже если переменная была расширена оболочкой, шаблон не будет совпадать во второй раз в цикле (, так как файл был изменен предыдущей итерацией ).
Вы перемещаете файл 1.txt
на первой итерации, что приведет к сбою команды sed
с ошибкой «Нет такого файла или каталога» на каждой последующей итерации.
Исправление этих трех проблем:
for number in {30..44}; do
sed '28 s/0\.340d0/0.'"$number"'0d0/' 1.txt >"$number.txt"
done
Обратите внимание, что я также удостоверяюсь, что точка в шаблоне соответствует буквальной точке, а не какому-либо символу (, что и сделал бы .
, если бы он не был экранирован как \.
или используется как[.]
). Я все еще использую одинарную кавычку для вашего выражения sed
, но я временно выхожу из нее, чтобы ввести значение в двойных кавычках из переменной оболочки number
.
Результат выполнения команды sed
записывается в имя файла, названное с помощью переменной number
.
Вместо того, чтобы адресовать строку по ее номеру, вы также можете использовать тот факт, что она начинается со строки rmin=
(, предполагая, что единственная строка , начинающаяся с этой строки):
for number in {30..44}; do
sed 's/^rmin=.*/rmin=0.'"$number"'0d0/' 1.txt >"$number.txt"
done
То же самое можно было бы сделать немного аккуратнее с помощьюawk
:
for number in {30..44}; do
awk -v num="$number" 'FNR == 28 { printf "rmin=0.%.2d0d0\n", num; next }; 1' 1.txt >"$number.txt"
done
Преимущество этого заключается в том, что он будет правильно вставлять число, даже если оно меньше 10 (, создавая 0.020d0
вместо 0.20d0
для 2
, например ).
Или сопоставление rmin=
в начале строки:
for number in {30..44}; do
awk -v num="$number" '/^rmin=/ { printf "rmin=0.%.2d0d0\n", num; next }; 1' 1.txt >"$number.txt"
done