Я выполнил приведенную ниже команду awk
пример файла
prqrtwtw
ahayqlo
prasqu
ожидаемый результат
prqrtwtw
ahayqlo
команда:
k=`awk -F "" '{print NF}' examplefile | sort -nr | sed -n '1p'`
for ((i=1;i<=$k;i++))
> do
> awk -v i="$i" -F "" '$i=="q" && $(i+1) !="u" {print $0}' examplefile;done
output
prqrtwtw
ahayqlo
В вашем конвейере есть несколько проблем.
Анализ выводаls
не является хорошей идеей(см. также Почему *не *parse `ls`(и что делать вместо )?). Его формат не стандартизирован, и имена файлов могут содержать любую комбинацию байтов, кроме NUL и /
. Следовательно, это не гарантирует, что имена файлов будут перечислены в однозначной форме. Часто приводимый пример включает символы новой строки (обратите внимание, как вызов ls
различными способами может привести к различным, возможно, неоднозначным результатам):
$ touch 'foo
> bar'
$ ls -1
'foo'$'\n''bar'
$ ls | cat
foo
bar
Являются ли foo
и bar
двумя разными файлами или двумя частями одного и того же имени файла?
Безопасным способом рекурсивного поиска в каталоге файлов данного типа являетсяfind
.
Неэкранированная строка l*
интерпретируется оболочкой как выражение подстановки . Он расширен до списка имен файлов (широким определением «файла» ), которые начинаются с l
в текущем каталоге.
# In a directory you created for testing purposes
$ rm *; touch foo; ln -s foo link1; ln -s foo link2; ln -s foo link3
$ set -x; ls -lR | grep l*
+ ls -lR
+ grep link1 link2 link3
Параметр xtrace
оболочки (, то есть set -x
, доступный в нескольких оболочках и указанный в POSIX ), полезен для демонстрации эффекта расширения имени файла (подстановки):l*
расширяется до link1 link2 link3
и grep
, следовательно, ищет строку link1
в содержимомfoo
(по символическим ссылкам link2
иlink3
).(grep
не читает стандартный ввод, когда ему дается список имен файлов после шаблона для поиска ).
Если у вас есть только один файл, имя которого начинается сl
:
# In a directory you created for testing purposes
$ rm *; touch foo; ln -s foo link1; ln -s foo Link2; ln -s foo Link3
$ set -x; ls -lR | grep l*
+ ls -lR
+ grep link1
lrwxrwxrwx 1 user group 3 May 1 03:04 link1 -> foo
Затем grep
ищет в своем стандартном вводе (выводls
)строку link1
, в данном случае совпадающую с одной строкой. (Чтение стандартного ввода — это то, что grep
делает, когда ему не заданы имена файлов или если аргумент имени файла -равен-
).
Вы должны заключать в кавычки литеральные строки, предназначенные для передачи в качестве аргументов, чтобы оболочка не выполняла расширение имени файла. В качестве альтернативы, если это поддерживается вашей оболочкой, расширение имени файла можно отключить с помощью set -f
.
Если имя файла в текущем каталоге не начинается с l
, выражение подстановки остается нетронутым и передается в grep
в качестве первого позиционного аргумента. grep
затем интерпретирует его как регулярное выражение (по умолчанию вариант BRE ), который гласит: «для любой строки ввода сопоставьте необязательноеl
(где угодно )», эффективно соответствие чему-либо:
# In a directory you created for testing purposes
$ rm *; touch foo
$ ls -lR
.:
total 0
-rw-r--r-- 1 user group 0 May 1 02:49 foo
$ set -x; ls -lR | grep l*
+ ls -lR
+ grep 'l*'
.:
total 0
-rw-r--r-- 1 user group 0 May 1 03:14 foo
Чтобы сопоставить строку, начинающуюся с литерала l
, вам нужно привязанное выражение:grep '^l'
.
Чтобы вы знали, команда, которую вы искали, это:
ls -l | grep '^l'
Кавычки не обязательны.
Удаление параметра -R
для ls
связано с тем, что вы указали, что вам нужен текущий каталог, а не дерево каталогов.
И в любом случае ответы, указывающие на find
, вероятно, являются лучшим решением.
@NasirRiley на правильном пути . Чтобы просмотреть символические ссылки в текущем каталоге, запустите find. -mindepth 1 -maxdepth 1 -type l
. Тест:
$ cd "$(mktemp --directory)"
$ mkdir foo
$ touch foo/bar baz
$ ln --symbolic foo/bar ban
$ ln --symbolic bar foo/bat # symlink in subdirectory, should be ignored
$ find. -mindepth 1 -maxdepth 1 -type l
./ban