Bash 스크립트의 변수에 할당

Bash 스크립트의 변수에 할당

다음 스크립트가 있고 빈 텍스트 파일을 만들려고 합니다. 시도하고 touch또 시도했지만 echo -n >실패했습니다.

#!/bin/bash

set filename_result="contents"

echo "filename=$filename_result" # Shows: filename=

rm -f "$filename_result".json

touch $filename_result # Error: usage: touch [-A [-][[hh]mm]SS] [-acfhm] [-r file] [-t [[CC]YY]MMDDhhmm[.SS]] file ...
# Note that `% touch myfile` works fine on the command line

touch -- "$filename_result" # Error: touch: : No such file or directory

echo -n > "$filename_result" # Error: No such file or directory

echo "[" >> "$filename_result"

for file in *json
do
    echo "examining file: $file"
    echo "\n" >> "$filename_result"
    cat $file >> "$filename_result"
    echo "\n" >> "$filename_result"
done

echo "\n]" >> "$filename_result"

mv $filename_result "$filename_result".json

편집: 화면 filename_result변수에 인쇄하면 설정 후 비어 있음이 표시됩니까?

echo "filename=$filename_result" # Shows: filename=

답변1

set filename_result="contents"할당된 값이 없습니다 filename_result. 첫 번째 위치 매개변수에 할당되며 값 자체는 입니다 filename_result=contents. 예:

$ set filename_result="contents"
$ echo "$1"
filename_result=contents

변수가 filename_result존재하지 않으며 $filename_result비어 있는 상태로 확장됩니다. "$filename_result"이는 와 동일합니다 "".

set filename_result="contents"딱 원하는 것 보다는

filename_result="contents"

답변2

이 시도:

filename_result=contents
touch -- "$filename_result"

또는:

set contents
touch -- "$1"

답변3

여러 JSON 파일의 콘텐츠를 요소로 포함하는 JSON 배열을 생성하려는 것 같습니다. 각 파일의 내용 사이에 쉼표 삽입을 생략한 것을 확인했습니다. 이로 인해 잘못된 JSON이 발생합니다.

대신 스크립트를 다음 명령으로 바꿀 수 있습니다.

jq -s . ./*.json >outfile

그러면 현재 디렉터리에서 이름이 일치하는 모든 파일을 읽고 *.json각 파일에 대한 JSON 문서를 하나의 요소로 사용하여 배열을 만듭니다. 출력이 기록됩니다 outfile.

jq대부분의 Unices에서 작동하는 명령줄 JSON 파서입니다(패키지 관리자를 확인하세요). -s(또는) 옵션은 --slurp방금 설명한 것과 정확히 일치합니다(배열로 읽기).

이것은 ."ID 필터"이며 그 역할은 데이터만 전달하는 것입니다.


귀하의 코드와 관련하여 :

변수를 설정하려는 시도 를 제외하고 set(이것은Kamil Machorovsky는 다음과 같이 지적했습니다.csh이미 이것이 쉘에서 수행되는 방식입니다 tcsh. 일부 명령(특히 루프 내부 명령)을 함께 그룹화하여 출력을 단순화할 수 있습니다. touch존재하지 않는 파일로 리디렉션하면 파일이 생성되므로 필요 하지 않습니다 .

다음은 문제에 대한 내 자신의 견해입니다. 각 파일의 내용 사이에 누락된 쉼표도 삽입됩니다.

#!/bin/sh

outfile=outfile

# Will truncate (empty) the file if it exists,
# or create it if it doesn't.
echo '[' >"$outfile"

# Get a list of all JSON files into the list
# of positional parameters.
set -- ./*.json

# Loop over all but the last file.
# Output each file and a comma.
while [ "$#" -gt 1 ]; do
    # The "current" file that we're working on is "$1",
    # the first one in the list.

    cat "$1"
    echo ,

    shift  # shifts this file off the list
done >>"$outfile

# The last file should not have comma after it.
{
    cat "$1"
    echo ']'
} >>"$outfile"

while루프는 위치 인수 목록(목록은 를 사용하여 생성됨 set)의 JSON 파일을 반복합니다. 각 파일 뒤에 쉼표를 붙여서 출력하고 싶지만, 마지막 파일 뒤에 쉼표가 오면 안 되기 때문에 별도로 처리합니다(이렇게 하면 JSON 형식이 손상됩니다). 따라서 루프는 목록의 마지막 파일( $#위치 인수 목록의 길이)을 제외한 모든 파일을 제거할 때까지 반복됩니다.

{ ...; }마지막 파일이 마지막 파일에 의해 처리됩니다. 중괄호 안에 명령 세트를 그룹화하면 단일 리디렉션을 통해 이러한 모든 명령의 출력을 한 번에 리디렉션할 수 있습니다. 마찬가지로 루프의 출력은 단일 리디렉션을 통해 리디렉션될 수 있습니다.


같은 방법이지만 GNU를 사용합니다 awk.

awk 'BEGIN   { print "[" }
             { print }
     ENDFILE { if (FILENAME != ARGV[ARGC-1]) print "," }
     END     { print "]" }' *.json

GNU에는 표준 및 블록(여기서는 출력 배열의 초기 및 최종 구분 기호 로 사용됨) awk외에 및 블록이 있습니다. 이는 (놀랍지도 않게) 각 개별 입력 파일이 처리되기 전후에 트리거됩니다. 여기서는 출력의 각 파일 내용 사이에 쉼표를 사용합니다(마지막 파일 다음은 제외).BEGINEND[]BEGINFILEENDFILEENDFILE

{ print }블록은 수정 없이 각 파일의 모든 줄을 전달합니다.

FILENAME, ARGV및 는 GNU가 자동으로 현재 파일 이름, 스크립트에 제공된 인수 목록(이 경우 파일 이름) 및 파일 이름 수로 자동으로 채우는 변수입니다 ARGC.awk

관련 정보