Bash 在传递到AWS S3之前更改查找命令输出
我必须Bash 在传递到AWS S3之前更改查找命令输出,bash,shell,amazon-web-services,amazon-s3,git-bash,Bash,Shell,Amazon Web Services,Amazon S3,Git Bash,我必须gzipCSS和JS文件并将它们上传到awss3 bucket。问题是当我运行gzip并尝试上传它们时,它们的初始目录结构并没有被保留。相反,它们都被复制到S3 bucket的根文件夹中。我意识到这是因为find命令返回输出的方式 $ find . -type f \( -iname \*.js -o -iname \*.css \) -exec gzip -9 "{}" \; -exec mv "{}.gz" "{}" \; -exec aws s3 cp "{}" s3://someb
gzip
CSS和JS文件并将它们上传到awss3 bucket。问题是当我运行gzip
并尝试上传它们时,它们的初始目录结构并没有被保留。相反,它们都被复制到S3 bucket的根文件夹中。我意识到这是因为find
命令返回输出的方式
$ find . -type f \( -iname \*.js -o -iname \*.css \) -exec gzip -9 "{}" \; -exec mv "{}.gz" "{}" \; -exec aws s3 cp "{}" s3://somebucket/ --dryrun \;
(dryrun) upload: .\service-worker.js to s3://somebucket/service-worker.js
(dryrun) upload: static\css\main.5b39ffb6.css to s3://somebucket/main.5b39ffb6.css
为了处理上述问题,我在目标路径中也使用了{}
,但现在的问题是最终路径具有/
(就在s3://somebucket/
之后),如下所示:
$ find . -type f \( -iname \*.js -o -iname \*.css \) -exec gzip -9 "{}" \; -exec mv "{}.gz" "{}" \; -exec aws s3 cp "{}" s3://somebucket/{} --dryrun \;
(dryrun) upload: .\service-worker.js to s3://somebucket/./service-worker.js
(dryrun) upload: static\css\main.5b39ffb6.css to s3://somebucket/./static/css/main.5b39ffb6.css
我想我可以使用cut
或sed
这样的方法从{}
中剥离/
部分,但当我尝试检查输出时,它会用不可读的东西装饰我的整个终端。似乎它不处理输出文件名,而是处理其内容。不知道发生了什么事
$ find . -type f \( -iname \*.js -o -iname \*.css \) -exec gzip -9 "{}" \; -exec mv "{}.gz" "{}" \; -exec sed 's#^./##' "{}" \;
有没有办法解决这个问题,使S3能够以正确的目录结构复制文件?您可以在
-exec
操作中创建子shell,并在其中操作文件名:
find . \
-type f \
\( -iname '*.js' -o -iname '*.css' \) \
-exec bash -c '
f=${1#./}
gzip "$f"
mv "$f".gz "$f"
aws s3 cp "$f" s3://somebucket/"$f" --dryrun' _ {} \;
-exec
操作运行一个命令bash-c'.{}
:一个命令列表,其中一个伪参数.
分配给$0
,文件名分配给$1
因为我们使用的是-exec
,所以文件路径看起来像/static/css/main.5b39ffb6.css
,也就是说,仍然包含我们想要删除的/
命令f=${1#./}
从路径的开头删除/
;从现在起,我们可以使用$f
您是对的,sed修改文件的内容,如果它们作为参数提供;要直接更改字符串,必须将管道连接到sed,如中所示
sed 's/x/y/' <<< 'A string with x'
您可以在
-exec
操作中创建子shell,并在其中操作文件名:
find . \
-type f \
\( -iname '*.js' -o -iname '*.css' \) \
-exec bash -c '
f=${1#./}
gzip "$f"
mv "$f".gz "$f"
aws s3 cp "$f" s3://somebucket/"$f" --dryrun' _ {} \;
-exec
操作运行一个命令bash-c'.{}
:一个命令列表,其中一个伪参数.
分配给$0
,文件名分配给$1
因为我们使用的是-exec
,所以文件路径看起来像/static/css/main.5b39ffb6.css
,也就是说,仍然包含我们想要删除的/
命令f=${1#./}
从路径的开头删除/
;从现在起,我们可以使用$f
您是对的,sed修改文件的内容,如果它们作为参数提供;要直接更改字符串,必须将管道连接到sed,如中所示
sed 's/x/y/' <<< 'A string with x'
您的
find
是否有-execdir
?如果是这样,您可以使用它来代替最后一个-exec
;在运行命令之前,它会更改为文件的目录。我现在正在gitbash
上尝试,但实际的命令将在Alpine或Ubuntu上运行,但无论如何,gitbash
具有-execdir
。一小时前我遇到了这个选项:)然而,这不起作用,我也这么认为。这不是简单地遍历到源文件的文件夹,并在目标中使用{}
,它应该简单地再次将文件复制到S3的根目录下吗?如果我错了,请纠正我。您的查找是否有-execdir
?如果是这样,您可以使用它来代替最后一个-exec
;在运行命令之前,它会更改为文件的目录。我现在正在gitbash
上尝试,但实际的命令将在Alpine或Ubuntu上运行,但无论如何,gitbash
具有-execdir
。一小时前我遇到了这个选项:)然而,这不起作用,我也这么认为。这不是简单地遍历到源文件的文件夹,并在目标中使用{}
,它应该简单地再次将文件复制到S3的根目录下吗?如果我错了,请纠正我。@Technext噢,我明白了。这是由-execdir
引起的,让我更新一下。@Technext相当不错;另外,还要注意@Technext如果使用{}+
,则必须处理bash-c
中的所有参数,即执行类似files=(“${}./}”)
的操作,然后处理该数组,而不是f=${1}
-不简单。@Technext因为-exec
中的bash-c
部分是单引号,所以必须进行一些扭曲才能扩展变量;类似于aws s3 cp“$f”“$s3_前缀/$bucket_名称”/“$f”
@Technext?它有一个我使用的引号混合的例子。@Technext哦,我明白了。这是由-execdir
引起的,让我更新一下。@Technext相当不错;另外,还要注意@Technext如果使用{}+
,则必须处理bash-c
中的所有参数,即执行类似files=(“${}./}”)
的操作,然后处理该数组,而不是f=${1}
-不简单。@Technext因为-exec
中的bash-c
部分是单引号,所以必须进行一些扭曲才能扩展变量;类似于aws s3 cp“$f”“$s3_前缀/$bucket_名称”/“$f”
@Technext?它有一个我使用的引号混合的例子。