Bash 스크립트에서 탭으로 구분된 파일을 반복합니다.

Bash 스크립트에서 탭으로 구분된 파일을 반복합니다.

이것이 내가 지금까지 가지고 있는 것입니다:

#!/bin/bash
while read line; do
        DB=$(echo $line | cut -f1)
        USER=$(echo $line | cut -f2)
        PASS=$(echo $line | cut -f3)
        echo DB=$DB USER=$USER PASS=$PASS
done < users.txt

입력 파일의 예:

drupal_1    drupal1 tmmjXSWL
drupal_2    drupal2 FHiJSYHM
drupal_3    drupal3 b7bFNj06
drupal_4    drupal4 0AaV62EL

그리고 스크립트의 출력은 다음과 같습니다.

DB=drupal_1 drupal1 tmmjXSWL USER=drupal_1 drupal1 tmmjXSWL PASS=drupal_1 drupal1 tmmjXSWL
DB=drupal_2 drupal2 FHiJSYHM USER=drupal_2 drupal2 FHiJSYHM PASS=drupal_2 drupal2 FHiJSYHM
DB=drupal_3 drupal3 b7bFNj06 USER=drupal_3 drupal3 b7bFNj06 PASS=drupal_3 drupal3 b7bFNj06

어떤 이유로 각 변수는 전체 행으로 설정됩니다. echo users.txt | cut -f1명령줄에서 사용 하면 토큰이 정상적으로 반환됩니다.

답변1

문제는 명령에 있습니다 echo $line. 주위에 따옴표가 없기 때문에 $line쉘은 단어 분할을 수행한 다음 각 단어를 와일드카드 패턴으로 해석합니다. 시도 해봐

a='*.txt foo'
ls $a

귀하의 경우 탭은 단어를 분리한 다음 별도의 인수가 됩니다 echo. 이 echo명령은 인수를 공백으로 구분하여 인쇄합니다. 따라서 cut탭으로 구분된 필드 대신 공백으로 구분된 필드를 받게 됩니다.

$foo변수 대체 및 명령 대체에는 항상 큰따옴표를 사용하세요.$(foo)(왜 제외해야 하는지, 왜 그렇게 할 수 있는지 이해하지 않는 한) echo "$line"여기서는 작동하지만 제안한 작업을 수행하는 복잡한 방법입니다.

셸에서 구문 분석 방법을 유지하면 read명령이 입력을 필드로 구문 분석하도록 할 수 있습니다.

while read DB USER PASS; do
  echo "DB=$DB USER=$USER PASS=$PASS"
done <users.txt

read변수 값을 문자로 구분된 필드로 분할합니다 IFS. 이 필드는 기본적으로 공백과 탭(한 줄에 나타날 수 없는 줄 바꿈 포함)으로 구성됩니다. 탭으로만 분할하려면 먼저 IFS단일 탭으로 설정하세요. 선행 및 후행 탭 문자는 무시되고 연속 탭 문자는 하나의 탭 문자로 처리됩니다.

read특수 문자 로 처리됩니다 \. 백슬래시 뒤에 개행 문자가 오면 \\단일 백슬래시가 됩니다. 이 동작을 방지하려면 이 -r옵션을 전달하십시오.

답변2

이건 어때?

$ awk '{print "DB="$1"\tUSER="$2"\tPASS="$3}' users.txt
DB=drupal_1 USER=drupal1    PASS=tmmjXSWL
DB=drupal_2 USER=drupal2    PASS=FHiJSYHM
DB=drupal_3 USER=drupal3    PASS=b7bFNj06
DB=drupal_4 USER=drupal4    PASS=0AaV62EL

해결해야 할 문제가 있는지, 아니면 좀 더 이론적인 것을 알고 싶은지 알 수 없습니다.

관련 정보