이것이 내가 지금까지 가지고 있는 것입니다:
#!/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
해결해야 할 문제가 있는지, 아니면 좀 더 이론적인 것을 알고 싶은지 알 수 없습니다.