Что делает эта командная строка (`echo $1 | xargs -n 1 basename | cut -d '.' -f1`)?

Что делает эта командная строка (`echo $1 | xargs -n 1 basename | cut -d '.' -f1`)?

Мне нужно понять эту командную строку:

file=`echo $1 | xargs -n 1 basename | cut -d '.' -f1`

решение1

Он присваивает бит имени файла (возможно, с путем) переменной file. А именно, бит перед первым .символом в имени файла самого файла. Другими словами, он берет что-то вроде /some/path/hello.worldи анализирует helloбит.

Совет: запускать каждую часть конвейера в командной строке:

$ thing="/some/path/hello.world"

$ echo "$thing"
/some/path/hello.world

$ echo "$thing" | xargs -n 1 basename
hello.world

$ echo "$thing" | xargs -n 1 basename | cut -d '.' -f 1
hello

Обратные кавычки используются для возврата выходных данных конвейера и назначения их file. $1Это первый аргумент в командной строке (для любого скрипта или функции оболочки, частью которой он является).

Вероятно, единственная причина xargs -n 1 basenameиспользования вместо plain basenameзаключается в том, что basenameутилита не считывает данные со стандартного ввода, а xargs.

Более короткая (и быстрая) версия того же самого в bashили ksh93будет

file=${1##*/}
file=${file%%.*}

решение2

Строка извлекает имена файлов без расширений из путей, предоставленных через $1(первый аргумент скрипта, в котором появляется эта строка). Результат сохраняется в переменной file.

Демонстрация:

$ echo /etc/dhcpcd.conf ../foo/bar/filename.tar.gz | xargs -n 1 basename | cut -d '.' -f1
dhcpcd
filename

решение3

Сочетание echoи xargsздесь весьма любопытно.

basenameберет путь в командной строке и выводит его конечный компонент (обычно часть после последнего слеша). xargsпросто помещает слова, считанные со своего ввода (канала), в командную строку здесь basename. Так почему бы просто не использовать basename $1?

Однако есть разница.

Если echo $1 | xargs -n 1 basenameпараметр $1содержит пробелы, xargsон будет разделен на пробелы и вызываться basenameдля каждого слова отдельно. Конечным результатом будет то, что часть имени файла будет выбрана длявсеслова, какАрминий показал.

Другой вариант, basename $1, вызовется basenameтолько один раз (и даст сбой в некоторых отношениях из-за разбиения слов).

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

file=$(basename "$1" | cut -d '.' -f 1)

С кавычками. (или с использованием расширения оболочки с удалением суффиксов ${file%%.*}вместо cutasКусалананда показал.)

С другой стороны, если предполагается обработка нескольких имен файлов, возможно, будет более разумно передать их с помощью массива или в позиционных параметрах (всех, а не только $1).

решение4

Строка сохраняет имя файла без расширения и пути в переменной $file.

В деталях:

echo $1печатает первый аргумент командной строки, переданный скрипту, xargs -n 1 basenameпередает отраженную строку в качестве аргументов команде basename, которая удаляет путь из имени файла. cut -d '.' -f1удаляет расширение.

Так, например, если вы выполните

echo directory/test.sh | xargs -n 1 basename | cut -d '.' -f1

результат (сохраненный в $file) будет test.

Связанный контент