попробуй
awk '$2 != 0 || $3 !=0 || $4 !=0 || $5 !=0 ' foo.txt
где
Редактировать:
«полная противоположность» немного нечеткая, однако, чтобы понять
$2 == 0 && $3 == 0 &&...
(&&
для логического и для awk, ||
для логического или)$2==0 || $3==0 ||...
если у вас много полей, чтобы строка была не нулевой:
awk 'NF>2 {for(i=2;i<=NF;i++) if ($i) {print ; next ;}}' file
где
NF
номер поля NF>2
убедитесь, что в строке есть как минимум 2 поля, а цикл for завершается. Это делает то, что вы хотите. Одна вещь :Я думаю, что это работает только в BASH. MAXDIGITS
не является обязательным, я поместил его туда на случай, если вам нужно работать с тройными цифрами или более. Если вы не используете его, удалите соответствующие строки.
#!/bin/bash
BOTTOM=$1
SHIFT=$2
MAXDIGITS=0$3
for filename in $(ls -r *.{txt,log}); do
PREFIX=${filename%%_*}
NEWPREFIX=$(expr $PREFIX + $SHIFT)
if [ $PREFIX -ge $BOTTOM ]; then
NEWPREFIX=$(printf %${MAXDIGITS}d $NEWPREFIX)
mv $filename ${NEWPREFIX}_${filename#*_}
fi
done
Чтобы использовать:
./myscript <BOTTOM> <SHIFT> <MAXDIGITS>
### Example:
./miscript 03 02 2 #This means "Start at 03_filename.*, shift the prefixes by 2 and use 2 digits to construct the new prefixes".
Если у вас есть другие файлы в том же каталоге, которые не соответствуют тому же синтаксису (префикс _имя файла.{txt,log} ), вы должны отфильтровать их. Кроме того, я использовал «_», чтобы отделить префикс от имени файла, поэтому, если вы измените его, вам нужно будет исправить код.
Вот bash
один -вкладыш, который включает две подстановки процессов и очень простую awk
процедуру:
$ ls -r -1 *_file_name.{txt,log} # list initial files in reverse order
05_file_name.log
05_file_name.txt
04_file_name.log
03_file_name.txt
03_file_name.log
03_file_name.txt
02_file_name.log
02_file_name.txt
01_file_name.log
01_file_name.txt
$ source <(awk 'BEGIN{FS="_"} $1>2 {prefix=$1+2; printf ("mv -f %s %0.2d_%s_%s\n",$0,prefix,$2,$3)}' <(ls -r -1 *_file_name.{log,txt}))
$ ls -1 *_file_name.{txt,log} # list resulting files
01_file_name.log
01_file_name.txt
02_file_name.log
02_file_name.txt
05_file_name.log
05_file_name.txt
06_file_name.log
06_file_name.txt
07_file_name.log
07_file_name.txt
Пояснение:
Одна строчка выше читается или, по крайней мере, «понятна» справа налево.
ls -r -1 *_file_name.{log,txt}
перечисляет все файлы, подлежащие обработке, в обратном порядке, в формате одного столбца -.
Обратите внимание, что если префиксы файлов (, обозначенные символом *
), включают не числовые символы -, вы можете получить непредвиденные/нежелательные результаты. Чтобы этого не произошло, отфильтруйте файлы, которые будут обрабатываться на этом этапе.
<(...)
замена процесса. Это позволяет ссылаться на предыдущий вывод результата с помощью дескриптора файла, то есть специального временного файла, называемого именованным каналом. Для получения подробной информации введите man bash
в терминале.
awk
сценарий:
BEGIN{FS="_"}
перед началом обработки записей установите разделитель полей записи на " _" (1-й блок awk)awk
условие второго блока,$1>2
:обрабатывает только те записи, префикс имени файла которых строго больше 2 prefix=$1+2
определяет внутреннюю переменную awk "prefix". Сделайте его численно равным префиксу $1
+ 2 printf("my_format",var1,var2,...)
для вывода отформатированных команд, разделенных новой строкой. Обратите внимание, что форматирование включает в себя %0.2d
, т. е. печать переменной «prefix» awk
в виде двухзначного числа -с заполнением 0, когда это необходимо. Вывод:mv -f 05_file_name.log 07_file_name.log
mv -f 05_file_name.txt 07_file_name.txt
mv -f 04_file_name.log 06_file_name.log
mv -f 04_file_name.txt 06_file_name.txt
mv -f 03_file_name.log 05_file_name.log
mv -f 03_file_name.txt 05_file_name.txt
mv -f...
. Если вам интересно, почему неоднократное использование подстановки входящих или исходящих процессов(не соответствует POSIX ! )в bash
выгодно, см., например, это .
Последнее примечание:
Включение параметров среды выполнения в один из вышеописанных вкладышей -и инкапсуляция их в исполняемый сценарий оболочки не представляет труда, начиная с определения VAR1
и VAR2
путем присвоения процедуре awk
:
$ source <(awk -v VAR1=2 -v VAR2=2 'BEGIN{FS="_"} $1>VAR1 {prefix=$1+VAR2; printf ("mv -f %s %0.2d_%s_%s\n",$0,prefix,$2,$3)}' <(ls -r -1 *_file_name.{log,txt}))
А в исполняемом скриптеscript.sh
:
$ cat script.sh
#!/usr/bin/bash
if [ "$#" -eq 2 ] ; then
source <(awk -v VAR1=$1 -v VAR2=$2 'BEGIN{FS="_"} $1>VAR1 {prefix=$1+VAR2; printf ("mv -f %s %0.2d_%s_%s\n",$0,prefix,$2,$3)}'
<(ls -r -1 *_file_name.{log,txt})
)
exit 0
else
echo " Usage: script.sh VAR1 VAR2.\n Abort execution (exit code 1)."
exit 1
fi
, где VAR1
и VAR2
имеют значение, определенное в OP. Если вам нужно использовать этот сценарий в производственной среде, я настоятельно рекомендую добавить ряд проверок и отказоустойчивых -сейфов, чтобы убедиться, что ваши входные файлы и значения переменных всегда являются ожидаемыми.
Сценарий @MarceloCastro хорош, хотя он основан на цикле for
, которого я стараюсь избегать, когда это возможно. for
Циклы, как правило, работают медленно, что можно заметить при обработке большого количества файлов.
Сzsh
:
$ autoload zmv
$ zmv -n -f '(<3->)(_*)(#qnOn)' '${(l:2::0:)$(($1+2))}$2'
mv -- 05_file_name.txt 07_file_name.txt
mv -- 05_file_name.log 07_file_name.log
mv -- 04_file_name.txt 06_file_name.txt
mv -- 04_file_name.log 06_file_name.log
mv -- 03_file_name.txt 05_file_name.txt
mv -- 03_file_name.log 05_file_name.log
Затем снимите-n
(для пробного -прогона ).
zmv pattern replacement
:zmv
— это автозагружаемая функция, которая использует мощные операторы zsh glob и расширения для сложного переименования файлов. <x-y>
сопоставляет десятичное число x и y. (#q...)
глобус квалификатор nOn
:n
умерически o
рдер (перевернутый с заглавной О )на n
аме. Таким образом, 05...
будет стоять перед 04...
по мере необходимости, так как мы увеличиваем числа. ${(l:n::padding:)expansion}
:l
ef дополнить расширение до длины n с помощью заполнения . Таким образом, с ${(l:2::0:)}
, левый блок до длины 2 с нулями. $(($1+2))
, первая захваченная группа увеличивается на 2. $2
:вторая группа захвата :что после ведущего числа.