bash를 사용하여 경로 문자열의 요소 하나 가져 오기


9

다음을 실행하여 읽은 파일 경로가 포함 된 ASCII 파일이 있습니다.

while read p; do echo $p; done < filelist.txt

파일에는 다음 패턴의 파일 경로가 포함됩니다.

./first/example1/path
./second/example1/path
./third/example2/path

어떻게 내가 (에서 경로 문자열의 특정 부분을 얻을 수 //), 예를 들어 내가 필요 출력 인쇄이를 얻을 :

first
second
third

그리고 또한

example1
example1
example2

정규 표현식을 사용 하여이 작업을 수행하는 방법이 있다고 확신 sed하지만에 익숙하지 않습니다.

답변:


17

사용 cut:

$ cat filelist.txt
./first/example1/path
./second/example1/path
./third/example2/path

$ cut -d/ -f2 filelist.txt 
first
second
third

$ cut -d/ -f3 filelist.txt 
example1
example1
example2

-d/로 컬럼 분리 설정 /-f2선택 2 열.

물론 파일 이름이나 파이프 데이터 대신 Bash 변수를 cut명령에 사용할 수도 있습니다 .

cut -d/ -f3 $MyVariable
echo ./another/example/path | cut -d/ -f3

| cut -d/ -f3 파이프에서 사용 하는 것이 트릭이었습니다. 감사! 이것은 전체 명령입니다 : while read p; do echo $p; done < filelist.txt | cut -d/ -f3
mcExchange

3
@mcExchange while 루프를 사용할 이유가 없습니다. 그냥 할 훨씬 간단합니다 cut -d/ -f3 filelist.txt
몬티을 열심히

1
또한 while을 피하면 인용 문제가 발생하지 않으며 파일 이름의 줄 바꿈으로 실패하지 않습니다.
Volker Siegel

10

변수를 read사용 하여 명령 에서 직접 수행 할 수 있습니다.IFS

$ while IFS=/ read -r p1 p2 p3 r; do echo "$p2"; done < filelist.txt 
first
second
third

5

당신이 사용할 수있는 awk

pilot6@Pilot6:~$ cat filelist.txt
./first/example1/path
./second/example1/path
./third/example2/path

pilot6@Pilot6:~$ awk -F "/" '{print $2}' filelist.txt
first
second
third

pilot6@Pilot6:~$ awk -F "/" '{print $3}' filelist.txt
example1
example1
example2

3

경로의 요소를 원하면 문자열을 필드로 나눌 수있는 것과 같은 것을 사용하는 것이 가장 좋습니다. , ,또는 . 하나, 패턴 대체를 사용하고 모든 것을 배열로 던지면서 매개 변수 대체로 작업을 수행 할 수도 있습니다.

$> echo ${FILE//\//\ }                                                         
sys class backlight intel_backlight brightness
$> ARRAY=( ${FILE//\//" " } )                                                  
$> echo ${ARRAY[2]}
backlight

$> FILE="./dir1/dir2/file.txt"                                                 
$> ARRAY=( ${FILE//\/" "} )
$> echo ${ARRAY[@]}                                                            
. dir1 dir2 file.txt
$> echo ${ARRAY[1]}
dir1

이제 우리는 경로로 만들어진 여러 항목을 가지고 있습니다. 경로에 공백이 포함 된 경우 내부 필드 구분 기호를 변경해야 할 수 있습니다 IFS.


1

Bash cut는 갈 길이지만 Perl을 사용하는 대안은 다음 과 같습니다.

perl -F/ -lane 'print(@F[1])' filelist.txt

두 번째로 /구분 된 필드

perl -F/ -lane 'print(@F[2])' filelist.txt

세 번째로 /구분 된 필드

  • -l: 자동 라인 엔딩 처리를 활성화합니다. 두 가지 별도의 효과가 있습니다. 먼저, -n 또는 -p와 함께 사용하면 $ / (입력 레코드 구분 기호)가 자동으로 숨겨집니다. 둘째, $ \ (출력 레코드 구분 기호)가 octnum 값을 갖도록 지정하여 모든 print 문에 해당 구분 기호가 다시 추가되도록합니다. octnum을 생략하면 $ \를 현재 값 $ /로 설정합니다.
  • -a: -n 또는 -p와 함께 사용하면 자동 분리 모드를 켭니다. @F 배열에 대한 암시 적 분할 명령은 -n 또는 -p에 의해 생성 된 암시 적 while 루프 내에서 첫 번째로 수행됩니다.
  • -n: Perl이 프로그램 주위에서 다음과 같은 루프를 가정하게하여 sed -n 또는 awk와 같은 파일 이름 인수를 반복합니다.

    LINE:
      while (<>) {
          ...             # your program goes here
      }
  • -e: 한 줄의 프로그램을 입력하는 데 사용될 수 있습니다.

  • print(@F[N]): N 번째 필드를 인쇄합니다.
% cat filelist.txt 
./first/example1/path
./second/example1/path
./third/example2/path
% perl -F/ -lane 'print(@F[1])' filelist.txt
first
second
third
% perl -F/ -lane 'print(@F[2])' filelist.txt
example1
example1
example2
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.