$ cat urls.txt
/var/www/example.com.com/upload/email/email-inliner.html
/var/www/example.com.com/upload/email/email.html
/var/www/example.com.com/upload/email/email2-inliner.html
/var/www/example.com.com/upload/email/email2.html
/var/www/example.com.com/upload/email/AquaTrainingBag.png
/var/www/example.com.com/upload/email/fitex/fitex-ecr7.jpg
/var/www/example.com.com/upload/email/fitex/fitex-ect7.jpg
/var/www/example.com.com/upload/email/fitex/fitex-ecu7.jpg
/var/www/example.com.com/upload/email/fitex/fitex.html
/var/www/example.com.com/upload/email/fitex/logo.png
/var/www/example.com.com/upload/email/fitex/form.html
/var/www/example.com.com/upload/email/fitex/fitex.txt
/var/www/example.com.com/upload/email/bigsale.html
/var/www/example.com.com/upload/email/logo.png
/var/www/example.com.com/upload/email/bigsale.png
/var/www/example.com.com/upload/email/bigsale-shop.html
/var/www/example.com.com/upload/email/bigsale.txt
有人可以帮我得到dirname
吗?
dirname /var/www/example.com.com/upload/email/sss.png
可以正常工作,但是URL列表呢?
是否可以不使用任何形式的循环(for
或while
)来实现这一点。由于URL的数量可能超过几千万。最好的方法是借助重定向(tee)到文件
答案 0 :(得分:3)
像往常一样,当它归结为这样的事情时,Awk会进行救援:
awk 'BEGIN{FS=OFS="/"}{NF--}1' <file>
请注意,这是dirname
的极为简化的版本,并没有与dirname
完全相同的实现,但是在大多数情况下都可以使用。涵盖所有情况的正确版本是:
awk 'BEGIN{FS=OFS="/"}{gsub("/+","/")}
{s=$0~/^\//;NF-=$NF?1:2;$0=$0?$0:(s?"/":".")};1' <file>
下表显示了区别:
| path | dirname | awk full | awk short |
|------------+---------+----------+-----------|
| . | . | . | |
| / | / | / | |
| foo | . | . | |
| foo/ | . | . | foo |
| foo/bar | foo | foo | foo |
| foo/bar/ | foo | foo | foo/bar |
| /foo | / | / | |
| /foo/ | / | / | /foo |
| /foo/bar | /foo | /foo | /foo |
| /foo/bar/ | /foo | /foo | /foo/bar |
| /foo///bar | /foo | /foo | /foo// |
注意:各种替代解决方案可以在Extracting directory name from an absolute path using sed or awk中找到。 Kent的解决方案都可以使用,Solid Kim的解决方案只需要进行微小的调整即可修复多个斜线(并错过投票!)