'/'문자를 포함하는 txt 파일의 이름으로 디렉토리를 작성하십시오.


8

이 같은 텍스트가 포함 된 .txt 파일이 있습니다

A1/B1/C1
A2/B2/C2 
A3/B3/C3

각 줄의 .txt 파일을 읽고 첫 번째 단어 (A1, A2, A3)를 기반으로 디렉토리를 만드는 스크립트를 원합니다.

다음과 같은 스크립트를 작성했습니다.

file="test.txt"
while IFS='' read -r line
do
    name="line"
    mkdir -p $line
done <"$file"

실행하는 동안 A1 디렉토리를 작성한 다음 하위 디렉토리 B1 및 C1도 작성합니다. 다른 라인 (A2 * 및 A3 *)에서도 마찬가지입니다.

A1, A2, A3 디렉토리 만 만들려면 어떻게해야합니까?

'/'문자가있는 A1 / B1 / C1과 같은 이름을 만들고 싶지 않습니다. '/'문자 앞에 단어를 가져 와서 디렉토리 이름으로 만들고 싶습니다. "A1" "A2" "A3"만 있습니다.

답변:


13

당신은 할 수 일 slash- 각 라인의 elimited 필드는 목록을 제공 :cut1dmkdir

mkdir $(<dirlist.txt cut -d/ -f1)

예제 실행

$ cat dirlist.txt 
A1/A2/A3
B1/B2/B3
C1/C2/C3
$ ls
dirlist.txt
$ mkdir $(<dirlist.txt cut -d/ -f1)
$ ls
A1  B1  C1  dirlist.txt

목록에 많은 수의 디렉토리 이름이있는 경우 ARG_MAX 문제가 발생할 수 있습니다 .이 경우 GNU를 사용 하거나 다음과 같이하십시오.parallel 병렬 설치xargs

parallel mkdir :::: <(<dirlist.txt cut -d/ -f1)
xargs -a<(<dirlist.txt cut -d/ -f1) mkdir

하지만 parallel이 덮여있다는 xargs디렉토리 이름에 공백이 포함 된 경우 접근하지 작업 것이다 - 당신이 중 하나를 사용할 수 있습니다 \0단순히 지시한다 라인 구분 기호로 또는 xargs(제안한 개행 문자의 입력을 분할 만에 마틴 보너 ) 대신 :

xargs -0a<(<dirlist.txt tr \\{n,0} | cut -d/ -f1 -z) mkdir # \\{n,0} equals \\n \\0
xargs -d\\n -a<(<dirlist.txt cut -d/ -f1) mkdir

필드에 줄 바꿈 문자가 포함 된 경우 "true"줄 끝을 식별하고 해당 줄 바꿈 문자 만 예를 들어로 바꿔야합니다 \0. 의 경우 일 것입니다 awk. 그러나 여기에서 너무 많이 가져온 것 같습니다.


xargs -a<(....)아니라 <dirlist.txt cut -d/ -f1 | xargs?
Martin Bonner는 Monica

1
@MartinBonner 명확히 해 주셔서 감사합니다. 실제로 제 tr접근 방식 보다 훨씬 간단 parallel합니다. 기본적으로 적용되는 것입니다.
디저트

@MartinBonner 파이프가 아닌 이유xargs -a<(....) –이 방법은 단순하기 때문에 좋아합니다. :)
디저트

@AndreaCorbellini 아, 이해합니다. <(...)공백에도 도움이되므로 확실히 더 나은 선택입니다. 어쨌든 아무도이 파일 설명자를 사용하고 있다고 생각하지 않습니다.
디저트

@MartinBonner 더 흥미롭게도 : cut <dirlist.txt대신에 cut dirlist.txt?
디저트

11

IFS='/'대해 설정 read한 다음 각 첫 번째 필드를 별도의 변수 first와 나머지 필드를 변수에 할당하고 첫 rest번째 필드의 값으로 작업하십시오 (또는 read -ar array단일 배열로하고 "${array[0]}"첫 번째 필드의 값으로 사용할 수 있음 ).

while IFS='/' read -r first rest;
do
    echo mkdir "$first" 
done < test.txt

또는 그것을 좋아하는 사람들을 위해 한 줄로 :

<test.txt xargs -d'\n' -n1 sh -c 'echo mkdir "$'{1%%/*}'"' _

또는 한 번에 모든 디렉토리를 작성하십시오.

<test.txt xargs -d'\n' bash -c 'echo mkdir "$'{@%%/*}'"' _

ANSI-C는 인용$'...' 특수 문자를 포함하는 디렉토리 이름을 처리하는 데 사용됩니다.

참고 그 _마지막 (또는 임의의 문자 스트링 일 수 있음)에 [0]는 argv 것 bash -c '...'$@의지 1부터 파라미터의 나머지를 포함 두 번째 명령이 없으면 첫 번째 매개 변수 mkdir가 손실됩니다.

에서 ${1%%/*}사용 쉘 (POSIX SH / 떠들썩한 파티 / 콘 / zsh을) 파라미터 교체 팽창 슬래시 모두 삭제 최장 매치에 의해 판독 라인 인 그것으로 전달 파라미터의 단부까지 아무것도 하였다 xargs를 ;

추신:

  • 제거 echo의 앞에 mkdir그 디렉토리를 만들 수 있습니다.
  • 교체 -d'\n'-0목록을 대신의 NUL 문자로 분리되어있는 경우 \newline (디렉토리 이름 / 임베디드 줄 바꿈이되어).

6

내용 test.txt:

A 12"x4" dir/B b/C c
A1/B1/C1
A2/B2/C2
A3/B3/C3

A[123]폴더 를 생성하는 스크립트 :

file="test.txt"
while read -r line ; do
   mkdir "${line%%/*}"
done < "$file"

출력 ls:

A 12"x4" dir
A1
A2
A3

다음과 같은 입력을 어떻게 처리 A 12"x4" dir/B b/C c합니까?
Ole Tange

Ole Tange-그 의견은 질문의 범위를 완전히 벗어난 것 같습니다.
DocSalvager

4

질문의 입력 예제에 표시된 것처럼 간단한 경우에는 via를 사용 cut 하여 출력을 mkdir전달하십시오.xargs

cut -f1 -d '/' file.txt | xargs -L1 mkdir 

디렉토리 이름에 공백이 포함될 수있는 경우를 처리 -d '\n'하기 위해 옵션 목록에 추가 할 수 있습니다.

$ cat input.txt 
A 1/B 1/C 1
A 2/B 2/C 2
A 3/B 2/C 2
$ cut -f1 -d '/' input.txt | xargs -d '\n' mkdir 
$ ls
A 1  A 2  A 3  input.txt

A 12"x4" dir/B b/C c주석에서 @OleTange가 제안한 것과 같이보다 복잡한 변형 awk의 경우 줄 바꿈으로 구분 된 목록 대신 null로 구분 된 목록을 만들 수 있습니다 .

awk -F'/' '{printf  "%s\0",$1}' input.txt |  xargs -0 mkdir

의견의 @dessert는 printf대신에 사용할 수 있는지 cut, 기술적으로 말하자면 인쇄 된 문자열을 3 자 너비로 제한하여 사용할 수 있는지 궁금해 했습니다.

xargs -d '\n' printf "%.3s\n"  < input.txt | xargs -L1 mkdir 

가장 깨끗한 방법은 아니지만 printf 사용할 수 있음을 증명 합니다. 물론, 디렉토리 이름이 3자를 초과하면 문제가됩니다.


다음과 같은 입력을 어떻게 처리 A 12"x4" dir/B b/C c합니까?
Ole Tange

@OleTange 편집 내용을 참조하십시오.
Sergiy Kolodyazhnyy

2

펄 사용하기 :

perl -ne 'mkdir for /^(\w+)/' list.txt

또는

perl -ne 'mkdir for /^([^\/]+)/' list.txt

dir-names에 공백을 허용하려면


1
perl -ne 'mkdir for /^([^\/]+)/' list.txtdir 이름의 공백을 포함합니다. 나는 마침내 Perl을 배울 필요가있다 – 감사합니다!
디저트

0

GNU Parallel은 작업에 과잉 일 수 있지만 각 줄마다 다른 작업을 수행하려는 경우 유용 할 수 있습니다.

cat myfile.txt | parallel --colsep / mkdir {1}
parallel -a myfile.txt --colsep / mkdir {1}

다음과 같은 입력을 올바르게 처리합니다.

A 12"x4" dir/B b/C c
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.