awk 重命名了几个文件并留下了几个重命名
awk renamed few files and left few to renamed
我正在尝试根据来自另一个文件的匹配文件名字符串替换部分文件名。文件名采用以下格式:
36872_20190806_00.csv 40800_20190806_00.csv 41883_20190806_00.csv
38064_20190806_00.csv 40848_20190806_00.csv 41891_20190806_00.csv
38341_20190806_00.csv 40856_20190806_00.csv 41923_20190806_00.csv
40417_20190806_00.csv 40948_20190806_00.csv 44373_20190806_00.csv
40745_20190806_00.csv 41217_20190806_00.csv 45004_20190806_00.csv
40754_20190806_00.csv 41256_20190806_00.csv
第一个 _
之前的数字代表电台代码,我想用另一个名为 radiosonde.csv
的文件中的电台名称替换它。例如:我想要
将36872_20190806_00.csv
更改为ALMATY_20190806_00.csv
将38064_20190806_00.csv
更改为KYZYLORDA_20190806_00.csv
radiosonde
的数据如下:
CODE,LAT,LON,Elevation,STN_NAME
41620,31.35,69.467,1407,ZHOB
41600,32.5,74.5333,255,SIALKOT
41598,32.9333,73.7167,232,JHELUM
41594,32.05,72.667,188,SARGODHA
41571,33.6167,73.1,507,ISLAMABAD_AIRPORT
41560,33.8667,70.0833,1725,PARACHINAR
41529,34.0333,71.9333,329,PESHAWAR
41516,35.9167,74.3333,1453,GILGIT
41515,35.5667,71.7833,1464,DROSH
41506,35.9217,71.8,1499,CHITRAL
41316,17.0439,54.1022,23,SALALAH_AIRPORT
41288,20.667,58.9,19,MASIRAH
41256,23.5953,58.2983,8.4,MUSCAT_INTL_AIRPORT
41217,24.4333,54.65,16,ABU_DHABI_INTL_AIRPOR
41169,25.2731,51.6081,4,HAMAD_INTL_AIRPORT
40990,31.5,65.85,1010,KANDAHAR_AIRPORT
40948,34.55,69.2167,1791,KABUL_AIRPORT
40938,34.217,62.217,977,HERAT
40913,36.6667,68.9167,433,KUNDUZ
40911,36.7,67.2,378,MAZAR-I-SHARIF
40875,27.2167,56.3667,10,BANDARABBASS
40856,29.4667,60.8833,1370,ZAHEDAN
40848,29.5333,52.6,1484,SHIRAZ
40841,30.25,56.9667,1748,KERMAN
40821,31.9,54.2833,1238,YAZD
40811,31.3333,48.6667,20,AHWAZ
40809,32.8667,59.2,1491,BIRJAND
40800,32.5175,51.7061,1550.4,ESFAHAN
40754,35.6833,51.3167,1204,TEHRAN-MEHRABAD
40745,36.2667,59.6333,999,MASHHAD
40427,26.267,50.617,2,BAHRAIN
40417,26.45,49.8167,22,KING_FAHD_INTL_AIRPORT
40416,26.267,50.167,19,DHAHRAN
3992,10.83,106.97,11,AN_LOC
38989,35.9,62.9667,375,TAGTABAZAR
38954,37.5,71.5,2077,KHOROG
38927,37.233,67.267,310,TERMEZ
38880,37.987,58.361,211,ASHGABAT_KESHI
38836,38.55,68.783,800,DUSHANBE
38750,37.467,53.967,-22,ESENGYLY
38687,39.083,63.6,190,CHARDZHEV
38613,40.917,72.95,765,DZHALAL-ABAD
38606,40.55,70.95,499,KOKAND
38599,40.217,69.733,427,KHUDJAND
38507,40.0333,52.9833,90,TURKMENBASHI
38457,41.267,69.267,493,TASHKENT
38413,41.733,64.617,237,TAMDY
38392,41.833,59.983,87,DASHKHOVUZ
38353,42.833,74.583,760,BISHKEK
38341,42.85,71.3,652,TARAZ
38064,44.7667,65.5167,133.4,KYZYLORDA
38001,44.55,50.25,-25,FORT SHEVCHENKO
37985,38.733,48.833,-11,LANKARAN
37860,40.5333,50,27,MASHTAGA
36974,41.433,76,2041,NARYN
36872,43.3633,77.0042,662.7,ALMATY
36859,44.167,80.067,645,ZHARKENT
3369,22.77,88.37,0,BARAKPUR
3368,25.88,89.43,0,LALMANIR_HAT
我调查了 this question。按照那里的建议,我试过了:
sort -r radiosonde.csv | awk -F"," '{print "for files in *00.csv; do mv $files ${files/" "/" "}; done" }' | bash
它在某种意义上确实起作用了。它重命名了一些文件并保留了一些文件并给出了错误:
bash: line 25: unexpected EOF while looking for matching `''
bash: line 113: syntax error: unexpected end of file
我不明白为什么它对某些文件的行为如此奇怪。如果我将这些文件名放入另一个文件中,请说 test.csv
并再次使用上面的命令,即
sort -r test.csv | awk -F"," '{print "for files in *00.csv; do mv $files ${files/" "/" "}; done" }' | bash
然后它将重命名之前留下的所有文件。有什么方法可以使用 shell 脚本来完成。我尝试了以下脚本但没有成功:
for file in *00.csv ; do
mv $files ${files/" "/" "};
done < radiosonde.csv
这个怎么样:
确保 radiosonde.csv
文件与所有要重命名的 csv
文件位于同一目录中。
$ cd <directory of radiosonde.csv, 36872_20190806_00.csv, 38064_20190806_00.csv and so on...>
$ ls *.csv > .tmp; awk -F ',' '{name[]=}END{for(;(getline filename < ".tmp")>0;){ori=filename;sub(/_.+$/,"",filename);pre=filename;sub(/^[0-9]+/,"",ori);post=ori;if(name[pre]!="")system("mv " pre post " " name[pre] post)}} ' 'radiosonde.csv'
$ rm -f '.tmp'
解释:
ls *.csv > .tmp
-> 列出当前目录中的所有文件并将它们写入 .tmp
awk -F ','
-> 将 ,
(逗号)设置为 awk 的字段分隔符。因为我们想将像 41620,31.35,69.467,1407,ZHOB
这样的行拆分成单独的字段。然后我们可以通过</code>、<code>
、</code>等方式获取它们。</li>
<li><code>'{ ... }END{}'
-> 这是 awk 的块。读取输入文件的第一个块和后面的块将在 awk 程序退出之前执行。
'radiosonde.csv'
将此设置为输入文件以供 awk 读取。
'{name[]=}'
-> </code> 是第一个字段,<code>
是第 5 个字段。在这种情况下,</code> 将是 <code>41620
、41600
等,而 </code> 将是 <code>ZHOB
、SIALKOT
等。名称是一个数组.当我们读取第一行时,我们为第二行设置name[CODE]=STN_NAME
和name[41620]=ZHOB
。
END{}'
-> 在我们设置了所有需要的变量之后,我们需要重命名文件,END{}
是我们可以用于该目的的块之一。
for(;(getline filename < ".tmp")>0;) {}
-> 这是用于读取 .tmp
包含我们要重命名的文件列表的文件。
ori=filename;
-> 将变量 filename
设置为另一个变量。这是因为我们想使用 sub()
函数来改变变量,但仍然需要 filename
变量来获取文件名的剩余部分。
sub(/_.+$/,"",filename);
-> 这是为了删除我们不想删除的字符。在这种情况下,从字符 _
到结尾。例如,如果 filename
为 41620_20190806_00.csv
,则 _20190806_00.csv
将被删除,并且 filename
将变为 41620
。
pre=filename;
-> 为清楚起见,将 filename
设置为另一个名为 pre
的变量。
sub(/^[0-9]+/,"",ori);
-> 这将删除前导数字,因此 ori
将变为 _20190806_00.csv
.
post=ori;
-> 在本例中将 ori
设置为另一个变量 post
.
if(name[pre]!="")
-> 因为 radiosonde.csv
将在 .tmp
中并且不是我们要重命名的文件之一,所以我们需要此 if
语句以便我们没有收到下一个命令的任何错误。 name[radiosonde]
将为空。
system("mv " pre post " " name[pre] post)
-> 该语句的作用是重命名您的文件。如果pre
是41620
,post
是_20190806_00.csv
,这个语句可以翻译成这个"mv 41620_20190806_00.csv ZHOB_20190806_00.csv"
.
rm -f '.tmp'
-> 删除 .tmp
文件,因为我们不再需要它了。
请忽略我下面的推荐。我们确实需要 if
语句。
我正在尝试根据来自另一个文件的匹配文件名字符串替换部分文件名。文件名采用以下格式:
36872_20190806_00.csv 40800_20190806_00.csv 41883_20190806_00.csv
38064_20190806_00.csv 40848_20190806_00.csv 41891_20190806_00.csv
38341_20190806_00.csv 40856_20190806_00.csv 41923_20190806_00.csv
40417_20190806_00.csv 40948_20190806_00.csv 44373_20190806_00.csv
40745_20190806_00.csv 41217_20190806_00.csv 45004_20190806_00.csv
40754_20190806_00.csv 41256_20190806_00.csv
第一个 _
之前的数字代表电台代码,我想用另一个名为 radiosonde.csv
的文件中的电台名称替换它。例如:我想要
将36872_20190806_00.csv
更改为ALMATY_20190806_00.csv
将38064_20190806_00.csv
更改为KYZYLORDA_20190806_00.csv
radiosonde
的数据如下:
CODE,LAT,LON,Elevation,STN_NAME
41620,31.35,69.467,1407,ZHOB
41600,32.5,74.5333,255,SIALKOT
41598,32.9333,73.7167,232,JHELUM
41594,32.05,72.667,188,SARGODHA
41571,33.6167,73.1,507,ISLAMABAD_AIRPORT
41560,33.8667,70.0833,1725,PARACHINAR
41529,34.0333,71.9333,329,PESHAWAR
41516,35.9167,74.3333,1453,GILGIT
41515,35.5667,71.7833,1464,DROSH
41506,35.9217,71.8,1499,CHITRAL
41316,17.0439,54.1022,23,SALALAH_AIRPORT
41288,20.667,58.9,19,MASIRAH
41256,23.5953,58.2983,8.4,MUSCAT_INTL_AIRPORT
41217,24.4333,54.65,16,ABU_DHABI_INTL_AIRPOR
41169,25.2731,51.6081,4,HAMAD_INTL_AIRPORT
40990,31.5,65.85,1010,KANDAHAR_AIRPORT
40948,34.55,69.2167,1791,KABUL_AIRPORT
40938,34.217,62.217,977,HERAT
40913,36.6667,68.9167,433,KUNDUZ
40911,36.7,67.2,378,MAZAR-I-SHARIF
40875,27.2167,56.3667,10,BANDARABBASS
40856,29.4667,60.8833,1370,ZAHEDAN
40848,29.5333,52.6,1484,SHIRAZ
40841,30.25,56.9667,1748,KERMAN
40821,31.9,54.2833,1238,YAZD
40811,31.3333,48.6667,20,AHWAZ
40809,32.8667,59.2,1491,BIRJAND
40800,32.5175,51.7061,1550.4,ESFAHAN
40754,35.6833,51.3167,1204,TEHRAN-MEHRABAD
40745,36.2667,59.6333,999,MASHHAD
40427,26.267,50.617,2,BAHRAIN
40417,26.45,49.8167,22,KING_FAHD_INTL_AIRPORT
40416,26.267,50.167,19,DHAHRAN
3992,10.83,106.97,11,AN_LOC
38989,35.9,62.9667,375,TAGTABAZAR
38954,37.5,71.5,2077,KHOROG
38927,37.233,67.267,310,TERMEZ
38880,37.987,58.361,211,ASHGABAT_KESHI
38836,38.55,68.783,800,DUSHANBE
38750,37.467,53.967,-22,ESENGYLY
38687,39.083,63.6,190,CHARDZHEV
38613,40.917,72.95,765,DZHALAL-ABAD
38606,40.55,70.95,499,KOKAND
38599,40.217,69.733,427,KHUDJAND
38507,40.0333,52.9833,90,TURKMENBASHI
38457,41.267,69.267,493,TASHKENT
38413,41.733,64.617,237,TAMDY
38392,41.833,59.983,87,DASHKHOVUZ
38353,42.833,74.583,760,BISHKEK
38341,42.85,71.3,652,TARAZ
38064,44.7667,65.5167,133.4,KYZYLORDA
38001,44.55,50.25,-25,FORT SHEVCHENKO
37985,38.733,48.833,-11,LANKARAN
37860,40.5333,50,27,MASHTAGA
36974,41.433,76,2041,NARYN
36872,43.3633,77.0042,662.7,ALMATY
36859,44.167,80.067,645,ZHARKENT
3369,22.77,88.37,0,BARAKPUR
3368,25.88,89.43,0,LALMANIR_HAT
我调查了 this question。按照那里的建议,我试过了:
sort -r radiosonde.csv | awk -F"," '{print "for files in *00.csv; do mv $files ${files/" "/" "}; done" }' | bash
它在某种意义上确实起作用了。它重命名了一些文件并保留了一些文件并给出了错误:
bash: line 25: unexpected EOF while looking for matching `''
bash: line 113: syntax error: unexpected end of file
我不明白为什么它对某些文件的行为如此奇怪。如果我将这些文件名放入另一个文件中,请说 test.csv
并再次使用上面的命令,即
sort -r test.csv | awk -F"," '{print "for files in *00.csv; do mv $files ${files/" "/" "}; done" }' | bash
然后它将重命名之前留下的所有文件。有什么方法可以使用 shell 脚本来完成。我尝试了以下脚本但没有成功:
for file in *00.csv ; do
mv $files ${files/" "/" "};
done < radiosonde.csv
这个怎么样:
确保 radiosonde.csv
文件与所有要重命名的 csv
文件位于同一目录中。
$ cd <directory of radiosonde.csv, 36872_20190806_00.csv, 38064_20190806_00.csv and so on...>
$ ls *.csv > .tmp; awk -F ',' '{name[]=}END{for(;(getline filename < ".tmp")>0;){ori=filename;sub(/_.+$/,"",filename);pre=filename;sub(/^[0-9]+/,"",ori);post=ori;if(name[pre]!="")system("mv " pre post " " name[pre] post)}} ' 'radiosonde.csv'
$ rm -f '.tmp'
解释:
ls *.csv > .tmp
-> 列出当前目录中的所有文件并将它们写入.tmp
awk -F ','
-> 将,
(逗号)设置为 awk 的字段分隔符。因为我们想将像41620,31.35,69.467,1407,ZHOB
这样的行拆分成单独的字段。然后我们可以通过</code>、<code>
、</code>等方式获取它们。</li> <li><code>'{ ... }END{}'
-> 这是 awk 的块。读取输入文件的第一个块和后面的块将在 awk 程序退出之前执行。'radiosonde.csv'
将此设置为输入文件以供 awk 读取。'{name[]=}'
-></code> 是第一个字段,<code>
是第 5 个字段。在这种情况下,</code> 将是 <code>41620
、41600
等,而</code> 将是 <code>ZHOB
、SIALKOT
等。名称是一个数组.当我们读取第一行时,我们为第二行设置name[CODE]=STN_NAME
和name[41620]=ZHOB
。END{}'
-> 在我们设置了所有需要的变量之后,我们需要重命名文件,END{}
是我们可以用于该目的的块之一。for(;(getline filename < ".tmp")>0;) {}
-> 这是用于读取.tmp
包含我们要重命名的文件列表的文件。ori=filename;
-> 将变量filename
设置为另一个变量。这是因为我们想使用sub()
函数来改变变量,但仍然需要filename
变量来获取文件名的剩余部分。sub(/_.+$/,"",filename);
-> 这是为了删除我们不想删除的字符。在这种情况下,从字符_
到结尾。例如,如果filename
为41620_20190806_00.csv
,则_20190806_00.csv
将被删除,并且filename
将变为41620
。pre=filename;
-> 为清楚起见,将filename
设置为另一个名为pre
的变量。sub(/^[0-9]+/,"",ori);
-> 这将删除前导数字,因此ori
将变为_20190806_00.csv
.post=ori;
-> 在本例中将ori
设置为另一个变量post
.if(name[pre]!="")
-> 因为radiosonde.csv
将在.tmp
中并且不是我们要重命名的文件之一,所以我们需要此if
语句以便我们没有收到下一个命令的任何错误。name[radiosonde]
将为空。system("mv " pre post " " name[pre] post)
-> 该语句的作用是重命名您的文件。如果pre
是41620
,post
是_20190806_00.csv
,这个语句可以翻译成这个"mv 41620_20190806_00.csv ZHOB_20190806_00.csv"
.rm -f '.tmp'
-> 删除.tmp
文件,因为我们不再需要它了。
请忽略我下面的推荐。我们确实需要 if
语句。