次のスクリプトがあり、空のテキストファイルを作成しようとしています。試して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ドキュメントを1つの要素として使用して配列を作成します。出力が記録されます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ファイルを繰り返します。各ファイルの後にコンマを付けて出力したいのですが、最後のファイルの後にコンマを付けてはいけません。したがって、ループは、リストの最後のファイル(位置$#
引数リストの長さ)を除くすべてのファイルが削除されるまで繰り返されます。
{ ...; }
最後のファイルは最後のファイルによって処理されます。中括弧内にコマンドセットをグループ化すると、単一のリダイレクトを介してこれらすべてのコマンドの出力を一度にリダイレクトできます。同様に、ループの出力は単一のリダイレクトを介してリダイレクトできます。
同じ方法ですが、GNUを使用してくださいawk
。
awk 'BEGIN { print "[" }
{ print }
ENDFILE { if (FILENAME != ARGV[ARGC-1]) print "," }
END { print "]" }' *.json
GNUには、標準とブロック(ここでは出力配列の最初と最後の区切り文字として使用されます)に加えて、awk
ブロックがあります。これは(驚くべきことに)各個々の入力ファイルが処理される前後にトリガされます。ここでは、出力の各ファイルの内容の間にカンマを使用します(最後のファイルの後は除く)。BEGIN
END
[
]
BEGINFILE
ENDFILE
ENDFILE
この{ print }
ブロックは、変更なしで各ファイルのすべての行を渡します。
FILENAME
、ARGV
およびは、GNUが自動的に現在のファイル名、スクリプトに提供されている引数のリスト(この場合はファイル名)、およびファイル名の数で自動的に入力する変数ですARGC
。awk