file
이름 목록이 포함된 목록이 있습니다 . 즉:
Long Name One (001)
Long Name Two (201)
Long Name Three (123)
...
공백과 일부 특수 문자가 포함됩니다. 다음과 같은 이름으로 디렉터리를 만들고 싶습니다.
cat file | xargs -l1 mkdir
이는 디렉토리가 공백으로 구분되도록 합니다(예: Long
, Name
, 대신 , One
, Two
, , ) .Three
Long Name One (001)
Long Name Two (201)
Long Name Three (123)
어떻게 해야 하나요?
답변1
사용-d '\n'
당신의 명령으로 xargs
:
cat file | xargs -d '\n' -l1 mkdir
맨페이지에서:
-d delim
Input items are terminated by the specified character. Quotes and backslash are not special; every
character in the input is taken literally. Disables the end-of-file string, which is treated like any
other argument. This can be used when the input consists of simply newline-separated items, although
it is almost always better to design your program to use --null where this is possible. The specified
delimiter may be a single character, a C-style character escape such as \n, or an octal or hexadecimal
escape code. Octal and hexadecimal escape codes are understood as for the printf command. Multibyte
characters are not supported.
출력 예:
$ ls
file
$ cat file
Long Name One (001)
Long Name Two (201)
Long Name Three (123)
$ cat file | xargs -d '\n' -l1 mkdir
$ ls -1
file
Long Name One (001)
Long Name Three (123)
Long Name Two (201)
답변2
xargs 구현이 -0
옵션을 지원하는 경우:
tr '\n' '\0' <file | xargs -0 -l1 mkdir
POSIX적으로:
while IFS= read -r file; do
mkdir -p -- "$file"
done <file
답변3
xargs
매우 특별한 입력 형식이 필요합니다. 여기서 인수는 공백이나 개행(현재 로케일에 따라 다른 형태의 수직 공백)으로 구분되며 작은 따옴표, 큰 따옴표 및 백슬래시를 사용하여 이스케이프할 수 있습니다(그러나 쉘 따옴표와 다른 방식).
-l1
입력 줄을 단일 인수로 전달하는 대신 각 입력 줄에 대해 호출이 이루어 mkdir
지지만 mkdir
해당 줄의 단어는 여전히 고유한 인수로 분리됩니다 mkdir
.
수십 년 전의 GNU 구현에는 NUL로 구분된 입력을 허용하는 옵션이 xargs
추가되었습니다 . -0
이는 결국 명령 인수가 될 단어를 분리하는 가장 확실한 방법입니다. 왜냐하면 NUL 문자는 명령 인수나 파일 이름(선택한 목록 형식에서는 한 줄에 하나의 파일을 입력함)에 나타날 수 없는 유일한 문자이기 때문입니다. 파일 이름에 개행 문자를 허용하지 않기 때문에 가능한 모든 파일 이름을 나타냅니다.
이것은 -0
여러 다른 구현에 의해 복사되었지만 xargs
전부는 아닙니다.
이를 통해 다음을 수행할 수 있습니다.
<file tr '\n' '\0' | xargs -0 mkdir -p --
mkdir
이는 가능한 한 많은 인수를 사용하여 가능한 한 적은 횟수로 호출됩니다 .
그러나 file
비어 있으면 계속 실행되며 mkdir
매개변수 누락으로 인해 구문 오류가 발생합니다. mkdir
GNU는 다른 구현에 의해 복사된 옵션을 xargs
추가했습니다 .-r
GNU는 xargs
(나중에) -d
임의의 구분 기호를 지정할 수 있는 옵션도 추가했지만 다른 구현에서는 이를 복제할 수 없을 것 같습니다. GNU의 경우 xargs
가장 좋은 접근 방식은 다음과 같습니다.
xargs -rd '\n' -a file mkdir -p --
-a
stdin 대신 GNU 확장자를 사용하여 파일을 전달하면 mkdir
stdin이 보존된다는 의미입니다.
POSIXly에서는 입력을 후처리하여 xargs
.
<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' | xargs mkdir -p --
"
xargs를 입력하기 전에 했던 것처럼 각 줄을 큰따옴표로 묶고 각 줄을 이스케이프 처리합니다 "\""
.
그러나 가능한 제한 사항에 유의하십시오.
- 파일이 비어있을 때 발생하는 오류는 위에 언급되어 있습니다.
sed
의 내용이file
현재 로케일에서 유효한 텍스트가 아닌 경우 일부 구현( 포함)이 실패할 수 있습니다. 여러 다른 문자 집합으로 인코딩된 파일 이름이 포함되어 있거나 로캘과 다른 문자 집합이 포함되어 있는 경우file
로캘을 C로 수정하면 도움이 됩니다.- 일부
xargs
구현에서는 매개변수의 최대 길이에 대한 제한이 매우 낮습니다(255바이트만큼 낮을 수 있음).
약빈 입력 시 구문 오류오류는 다음과 같이 작성할 수 있습니다.
<file sed 's/"/"\\""/g; s/^/"/; s/$/"/' |
xargs sh -c '[ "$#" -eq 0 ] || exec mkdir -p -- "$@"' sh
답변4
다음 옵션을 사용하여 POSIXLY로 이 작업을 수행할 수 있습니다 -I
.
xargs -I % mkdir % < file
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/xargs.html