削除・名前変更できないファイル名やフォルダ名をシェルの特殊パラメーターで操作する on NAS via SSH

## 操作できないファイルやフォルダがある

<img width="100%" alt="消せない謎のファイル.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78776/84da4599-4dfb-1e67-0808-13c455b3532d.png">

> - 共有フォルダ上のフォルダやファイルの**削除や名前変更などの操作するとエラーが発生する**。<br><br>例えば macOS の場合は「操作を完了できません。予期しないエラーが起きました（エラーコード-43）」などと表示される。
> 
> - macOS に限らず、ターミナルや SSH 接続して操作しようとするも「そんなファイルやフォルダはない」と言われる。
>
> - しかし `ls` や `ls -d` では一覧に表示される。`sudo` 権限で削除しても NG。所有権やアクセス権も問題なさそうであるし、ファイルを開いたり編集・保存はできる。

## TS;DR

> **<font color=blue>`ls` コマンドで対象ファイルに絞り込んだのち、`$_` の特殊パラメーター変数を使って操作する</font>**

```shell-session:基本的な使い方
$ ls *foo*bar*.mp4 && mv "$_" "ShortAndRightFileOfFooBar.mp4"
```

ファイルやディレクトリの**名前が長すぎ**たり、"[ZWSP](https://ja.wikipedia.org/wiki/%E3%82%BC%E3%83%AD%E5%B9%85%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9)" などの不可視文字といった**特殊文字や制御コード文字が含まれている**と、コピー時に正規化されることがあります。そのため、ペースト時にはオリジナルと異なるファイル名になったことが原因と思われます。

<details><summary>使い方の実例</summary><div><br>

```shell-session:使い方の実例
$ # 対象ファイルを探す
$ ls -l
file1.mp3
I'm とてつもなく fu ⋆ king-長い file and with spaces しかも日本語ファイル​​🎉.mp4
file3.wav
$ 
$ # 削除できない
$ rm -f "I'm とてつもなく fu ⋆ king-長い file and with spaces しかも日本語ファイル🎉.mp4"
rm: cannot remove `I'm とてつもなく fu ⋆ king-長い file and with spaces しかも日本語ファイル🎉.mp4': No such file or directory
$
$ # 検索結果を対象ファイル１つに絞る
$ ls *file*spaces*.mp4
I'm とてつもなく fu ⋆ king-長い file and with spaces しかも日本語ファイル​​🎉.mp4
$
$ # 特殊変数 $_ にセットされた内容を確認する
$ echo $_
I'm とてつもなく fu ⋆ king-長い file and with spaces しかも日本語ファイル​​🎉.mp4
$
$ # 以上を組み合わせて `mv` コマンドで短くリネーム
$ ls *file*spaces*.mp4 && mv "$_" "I am short and right file.mp4"
I'm とてつもなく fu ⋆ king-長い file and with spaces しかも日本語ファイル​​🎉.mp4
$
$ # リネームの結果確認
$ ls -l
file1.mp3
I am short and right file.mp4
file3.wav
$
$ # 安心して削除
$ rm "I am short and right file.mp4"
$ ls -l
file1.mp3
file3.wav
```

</div></details>

## TL;DR（詳細）

<img width="100%" title="操作を完了できません。予期しないエラーが起きました（エラーコード-43）" alt="操作を完了できません。予期しないエラーが起きました（エラーコード-43）" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78776/0ff4c2a8-03d3-5f4a-2e41-bb4cfdb6e2ea.png">

ネットからスクラップしたデータや大きなファイルを、NAS（QNAP）の共有フォルダをマウントして１箇所で管理してます。

長ったらしいファイル名があったので短くしようと `finder` からファイル操作すると、「操作を完了できません。」エラーが発生するファイルがあることに気づきました。

どうやらファイルを保存する際に、ファイル名をそのままで保存したり、フォルダ名をサイトからコピペしたものを使ったことが原因で、URL がファイル名だったり、特殊文字が含まれた状態で保存してしまったようです。

**よく考えずに、横着でコピペすると[コピペピピック](https://qiitadon.com/@KEINOS/99692402654853280)なことが起きる**典型的な例です。

### コピペできないコピペピピックなファイル名は特殊パラメーターで操作する

`finder` などの GUI シェルから操作ができない場合は、ターミナルからシェル操作するのが王道です。

SSH で NAS（QNAP）にログインして `ls` で表示されたファイルをコピペして `rm` したのですが、失敗しました。

```shell-session
$ ssh -l user1 NAME_OF_MY_NAS.local
...
[~] # 
[~] # # QNAP で日本語が扱えるようにシェルを ash に変更
[~] # ash

BusyBox v1.01 (2019.01.01-19:01+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.

[/root] # 
[/root] # # 削除したいディレクトリに移動
[/root] # cd /share/HDA_DATA/MyFiles
[/share/HDA_DATA/MyFiles] # # ファイル一覧を確認
[/share/HDA_DATA/MyFiles] # ls
file1.mp3
I'm とてつもなく fu ⋆ king-長い file and with spaces しかも日本語ファイル​​🎉.mp4
file3.wav
[/share/HDA_DATA/MyFiles] # # ファイル名をコピペして削除
[/share/HDA_DATA/MyFiles] # rm "I'm とてつもなく fu ⋆ king-長い file and with spaces しかも日本語ファイル​​🎉.mp4"
rm: cannot remove `I'm とてつもなく fu ⋆ king-長い file and with spaces しかも日本語ファイル​​🎉.mp4': No such file or directory

```

シングルクォートをエスケープしてもダメでした。ターミナル上でコピーすると正規化されるのか、ペーストするとオリジナルのファイル名と変わるため削除できないようです。

「検索したファイル名をコピペせずに、そのまま `rm` や `mv` コマンドに渡せばいいのでは」と考えたところ、以下の２つの記事を思い出しました。

- 「[mkdir と同時に cd でディレクトリ移動させるには（空白入りディレクトリ名の場合）](https://qiita.com/KEINOS/items/1da5ca6443bd7f254119)」 @ Qiita

    ```bash
    mkdir "my dir with spaces" && cd "$_"
    ```

- 「[多数のファイルから一つだけ（最後のファイルだけ）を開く手順](https://qiita.com/7of9/items/ebfaa2367fe3f9e19e1b)」@ Qiita

    ```bash
    ls *.log && vi $_
    ```

そして、この２つのテクニックを使って「`mv` コマンドでファイル名を短くかつ特殊な状態を回避」してから「`rm` コマンドで削除」すればいいと考え、最終的に以下のように落ち着きました。

```shell-session
$ ls *some*thing*to*hit.txt && mv "$_" "shortname.txt"
...
$ rm shortname.txt
...
```