변수 또는 명령 출력에서 bash의 행을 어떻게 올바르게 반복합니까? IFS 변수를 새 행으로 설정하면 명령 출력에 효과적이지만 새 행이 포함 된 변수를 처리 할 때는 작동하지 않습니다.
예를 들어
#!/bin/bash
list="One\ntwo\nthree\nfour"
#Print the list with echo
echo -e "echo: \n$list"
#Set the field separator to new line
IFS=$'\n'
#Try to iterate over each line
echo "For loop:"
for item in $list
do
echo "Item: $item"
done
#Output the variable to a file
echo -e $list > list.txt
#Try to iterate over each line from the cat command
echo "For loop over command output:"
for item in `cat list.txt`
do
echo "Item: $item"
done
출력이 나타납니다.
echo:
One
two
three
four
For loop:
Item: One\ntwo\nthree\nfour
For loop over command output:
Item: One
Item: two
Item: three
Item: four
보시다시피, 변수를 반향하거나 cat
명령을 반복 하면 각 줄이 하나씩 올바르게 인쇄됩니다. 그러나 첫 번째 for 루프는 모든 항목을 한 줄에 인쇄합니다. 어떤 아이디어?
답변
bash를 사용하면 문자열에 줄 바꿈을 포함하려면 문자열을 $''
다음 과 같이 묶으십시오 .
$ list="One\ntwo\nthree\nfour"
$ echo "$list"
One\ntwo\nthree\nfour
$ list=$'One\ntwo\nthree\nfour'
$ echo "$list"
One
two
three
four
그리고 변수에 이미 그러한 문자열이 있다면 다음을 사용하여 한 줄씩 읽을 수 있습니다.
while read -r line; do
echo "... $line ..."
done <<< "$list"
답변
while
+ 를 사용할 수 있습니다 read
:
some_command | while read line ; do
echo === $line ===
done
Btw. -e
에 대한 옵션은 echo
비표준입니다. printf
이식성을 원한다면 대신 사용하십시오 .
답변
#!/bin/sh
items="
one two three four
hello world
this should work just fine
"
IFS='
'
count=0
for item in $items
do
count=$((count+1))
echo $count $item
done
답변
for 루프를 수행하는 재미있는 방법은 다음과 같습니다.
for item in ${list//\\n/
}
do
echo "Item: $item"
done
조금 더 현명하고 읽기 쉬운 것은 다음과 같습니다.
cr='
'
for item in ${list//\\n/$cr}
do
echo "Item: $item"
done
그러나 그것은 너무 복잡하기 때문에 거기에 공간 만 있으면됩니다.
for item in ${list//\\n/ }
do
echo "Item: $item"
done
당신 $line
변수는 줄 바꿈이 포함되어 있지 않습니다. \
뒤에 오는
인스턴스가 포함되어 있습니다 n
. 당신은 그것을 명확하게 볼 수 있습니다 :
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo $list | hexdump -C
$ ./t.sh
00000000 4f 6e 65 5c 6e 74 77 6f 5c 6e 74 68 72 65 65 5c |One\ntwo\nthree\|
00000010 6e 66 6f 75 72 0a |nfour.|
00000016
대체는 공백으로 공백을 대체하므로 for 루프에서 작동하기에 충분합니다.
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo ${list//\\n/ } | hexdump -C
$ ./t.sh
00000000 4f 6e 65 20 74 77 6f 20 74 68 72 65 65 20 66 6f |One two three fo|
00000010 75 72 0a |ur.|
00000013
데모:
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo ${list//\\n/ } | hexdump -C
for item in ${list//\\n/ } ; do
echo $item
done
$ ./t.sh
00000000 4f 6e 65 20 74 77 6f 20 74 68 72 65 65 20 66 6f |One two three fo|
00000010 75 72 0a |ur.|
00000013
One
two
three
four
답변
먼저 변수를 배열로 변환 한 다음이 과정을 반복 할 수도 있습니다.
lines="abc
def
ghi"
declare -a theArray
while read -r line
do
theArray+=($line)
done <<< "$lines"
for line in "${theArray[@]}"
do
echo "$line"
#Do something complex here that would break your read loop
done
이것은 루프 내에서 다른 스크립트를 호출하여 해당 스크립트가 반환 버퍼를 비우기 전에 반환 버퍼를 비울 수있는 루프에서 다른 스크립트를 호출하면 발생할 수 IFS
있으므로 read
명령에 문제가있는 경우에만 유용합니다 . .